home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-04-27 | 4.6 KB | 259 lines | [TEXT/MPS ] |
-
- #include "UDP.h"
- #include "InetD.h"
-
- #include <UFailure.h>
- #include <myUtils.h>
-
- #include <Resources.h>
- #include <Devices.h>
- #include <Processes.h>
- #include <Desk.h>
-
- UDPListener::UDPListener(InetD* daemon)
- {
- fDaemon = daemon;
- }
-
- UDPListener::~UDPListener()
- {
- this->Release();
- }
-
- Boolean
- UDPListener::Initialize()
- {
- int numPBs;
- int i;
-
- Handle resHandle;
- short theID;
- ResType theType;
- Str255 theName;
-
- numPBs = CountResources('UDP ');
- if (numPBs > 0) {
- for (i = 1; i <= numPBs; i++) {
- resHandle = GetIndResource('UDP ', i);
- FailResError();
-
- GetResInfo(resHandle, &theID, &theType, theName);
- this->ListenOn((udp_port) theID);
-
- ReleaseResource(resHandle);
- }
-
- return true;
- }
- else
- return false;
- }
-
- void
- UDPListener::DoNull()
- {
- PortItem* item;
- Handle resHandle;
- FailInfo fi;
-
- while ((item = (PortItem*) fLaunchList.First()) != nil) {
- resHandle = GetResource('UDP ', item->fPort);
- FailResError();
-
- HLock(resHandle);
-
- fDaemon->LogIt(false, "Attempting to launch %P\n", ((FSSpec*) *resHandle)->name);
-
- if (fi.Try()) {
- fDaemon->Launch(item->fStream, (FSSpec*) *resHandle, 'USTR', &item->fPSN);
- fi.Success();
- }
- else {
- this->CloseDown(item->fStream);
- fDaemon->LogIt(true, "InetD:\n\nFailed to launch %P for UDP port %d",
- ((FSSpec*) *resHandle)->name, item->fPort);
- }
-
- fLaunchList.TakeOff(item);
- fRestartList.PutOn(item);
-
- HUnlock(resHandle);
- ReleaseResource(resHandle);
- }
- }
-
- void
- UDPListener::ListenOn(udp_port thePort)
- {
- UDPiopb pb;
- Ptr rcvPtr = nil;
- PortItem* nu;
-
- rcvPtr = NewPtrSys(4 * 1024);
- FailMemError();
-
- pb.ioCompletion = nil;
- pb.csCode = UDPCreate;
- pb.ioCRefNum = fDaemon->GetDriver();
- pb.csParam.create.rcvBuff = rcvPtr;
- pb.csParam.create.rcvBuffLen = 4 * 1024;
- pb.csParam.create.localPort = thePort;
- pb.csParam.create.notifyProc = &UDPNotify;
- pb.csParam.create.userDataPtr = (Ptr) this;
-
- FailOSErr(PBControlSync((ParmBlkPtr) &pb));
-
- nu = new PortItem;
- FailNIL(nu);
-
- nu->fStream = pb.udpStream;
- nu->fPort = pb.csParam.create.localPort;
- nu->fDaemon = fDaemon;
-
- fWaitList.PutOn(nu);
- }
-
- void
- UDPListener::CloseDown(StreamPtr stream)
- {
- UDPiopb pb;
-
- pb.csCode = UDPRelease;
- pb.ioCRefNum = fDaemon->GetDriver();
- pb.udpStream = stream;
-
- FailOSErr(PBControlSync((ParmBlkPtr) &pb));
-
- DisposePtr(pb.csParam.create.rcvBuff);
- FailMemError();
- }
-
- void
- UDPListener::Release()
- {
- PortItem* item;
-
- while ((item = (PortItem*) fWaitList.First()) != nil) {
- this->CloseDown(item->fStream);
- fWaitList.TakeOff(item);
- delete item;
- }
-
- while ((item = (PortItem*) fLaunchList.First()) != nil) {
- this->CloseDown(item->fStream);
- fLaunchList.TakeOff(item);
- delete item;
- }
- }
-
- void
- UDPListener::NotifyMe(PSNPtr psn, StreamPtr stream, ProcPtr proc, Ptr usr)
- {
- PortItem* nu = new PortItem;
- FailNIL(nu);
-
- nu->fPSN.highLongOfPSN = psn->highLongOfPSN;
- nu->fPSN.lowLongOfPSN = psn->lowLongOfPSN;
- nu->fStream = stream;
- nu->fProc = proc;
- nu->fUsrPtr = usr;
-
- fNoteeList.PutOn(nu);
- }
-
- /* These currently gets called with the PSN of every app that
- we launch, even the ones that don't request ASR service,
- hence its okay if the notee isn't found.
- */
- void
- UDPListener::UnNotify(PSNPtr psn)
- {
- PortItem* old;
-
- old = fNoteeList.GetItem(psn);
- if (old) {
- fNoteeList.TakeOff(old);
- delete old;
- }
- }
-
- void
- UDPListener::ListenAgain(PSNPtr psn)
- {
- PortItem* old;
- udp_port port;
-
- old = fRestartList.GetItem(psn);
- if (old) {
- fRestartList.TakeOff(old);
- port = old->fPort;
- delete old;
-
- this->ListenOn(port);
- }
- }
-
- PortItem::PortItem()
- {
- fPort = 0;
-
- fStream = nil;
- fProc = nil;
- fUsrPtr = nil;
- fPSN.highLongOfPSN = 0;
- fPSN.lowLongOfPSN = 0;
-
- fDaemon = nil;
- }
-
- PortItem*
- UPortList::GetItem(PSNPtr psn)
- {
- PortItem* it = (PortItem*) this->First();
-
- while (it && (!SameProcesses(psn, &it->fPSN)))
- it = (PortItem*) it->fNext;
-
- return it;
- }
-
- PortItem*
- UPortList::GetItem(StreamPtr stream)
- {
- PortItem* it = (PortItem*) this->First();
-
- while (it && (stream != it->fStream))
- it = (PortItem*) it->fNext;
-
- return it;
- }
-
- pascal void
- UDPNotify( StreamPtr stream,
- unsigned short eventCode,
- Ptr usrData,
- struct ICMPReport* icmp)
- {
- PortItem* them;
- UDPListener* udp = (UDPListener*) usrData;
-
- if (eventCode == UDPDataArrival) {
- them = udp->fWaitList.GetItem(stream);
- if (them) {
- udp->fWaitList.TakeOff(them);
- udp->fLaunchList.PutOn(them);
- WakeUpProcess(&them->fDaemon->fPSN);
- return;
- }
- }
-
- /* if we get here, the event wasn't for a connection
- i'm mantaining, therefore it needs to be passed
- on to whoever is.
- */
- them = udp->fNoteeList.GetItem(stream);
- if (them && them->fProc)
- (*(UDPNotifyProc) them->fProc)(stream, eventCode, them->fUsrPtr, icmp);
- }
-
-